#include "LCD_Handler.h"

#pragma MESSAGE DISABLE C3401
#pragma MESSAGE DISABLE C1825

const uint8 u8M_INIT1[16] = {"   Waiting for  "};
const uint8 u8M_INIT2[16] = {" sensor manager "};

extern const uint8 u8M19[16];

uint8 u8LCD_Buffer1[16];// = { "----------------" };
uint8 u8LCD_Buffer2[16];// = { "----------------" };
uint8 u8LCD_Buffer3[16];// = { "----------------" };
uint8 u8LCD_Buffer4[16];// = { "----------------" };
uint8 u8LCD_cursor1 = 0x85;
uint8 u8LCD_cursor2 = 0xCD;

const uint8 u8MLCD_INIT1[16] = {"   SMAC Based   "};
const uint8 u8MLCD_INIT2[16] = {" Plane Platform "};

const uint8 u8MLCD_INIT3[16] = {"     ITESO      "};
const uint8 u8MLCD_INIT4[16] = {"  www.iteso.mx  "};

uint8 u8LCD_ControllerBatt = 100;
uint8 u8LCD_AirplaneBatt = 100;
uint8 u8LCD_Signal = 0;
uint8 u8LCD_MotorTemp = 0;
uint8 u8LCD_DriverTemp = 0;
uint8 u8LCD_AmbientTemp = 0;
uint16 u16LCD_Distance = 0;
uint8 u8LCD_Velocity = 0;
uint8 u8LCD_Direction = 0;


void vfnLCD_GPIO_Init (void)
{
    LCD_DATA_7_DD = GPIO_OUTPUT;
    LCD_DATA_6_DD = GPIO_OUTPUT;
    LCD_DATA_5_DD = GPIO_OUTPUT;
    LCD_DATA_4_DD = GPIO_OUTPUT;
    
    LCD_RS_DD = GPIO_OUTPUT;
    LCD_EN_1_DD = GPIO_OUTPUT;
    LCD_EN_2_DD = GPIO_OUTPUT;
}

void vfn_LCD_MenuSelLine(uint8 u8line)
{
    if (u8line == 1)
    {
        u8LCD_Buffer1[1] = 0x02;
    }
    else if (u8line == 2)
    {
        u8LCD_Buffer2[1] = 0x02;
    }
    else if (u8line == 3)
    {
        u8LCD_Buffer3[1] = 0x02;
    }
    else if(u8line == 4)
    {
        u8LCD_Buffer4[1] = 0x02;
    }
}

void vfnLCD_SendData (uint8 u8lcd, uint8 u8data)
{
    uint8 u8lcd_4bit = 2;
    
    while (u8lcd_4bit)
    {
        
        if (u8data & 0x80)
        {
            LCD_DATA_7 = 1;
        }
        else
        {
            LCD_DATA_7 = 0;
        }
        
        if (u8data & 0x40)
        {
            LCD_DATA_6 = 1;
        }
        else
        {
            LCD_DATA_6 = 0;
        }
        
        if (u8data & 0x20)
        {
            LCD_DATA_5 = 1;
        }
        else
        {
            LCD_DATA_5 = 0;
        }
        
        if (u8data & 0x10)
        {
            LCD_DATA_4 = 1;
        }
        else
        {
            LCD_DATA_4 = 0;
        }
        
        LCD_SEND_CLOCK()
        
        u8lcd_4bit--;
        u8data <<= 4;
    }
    
    vfnLCD_Delay (DELAY_40US);
}

void vfnLCD_InitMessage()
{
	  uint16 u16tempo = 750;
	  
  	  vfnLCD_SendLine(1, u8MLCD_INIT1);
	  vfnLCD_SendLine(2, u8MLCD_INIT2);

	  while(--u16tempo)
	  {
	 	vfnLCD_Delay(DELAY_2MS);
	  }
	  
  	  vfnLCD_SendLine(3, u8MLCD_INIT3);
	  
	  u16tempo = 250;

	  while(--u16tempo)
	  {
	 	vfnLCD_Delay(DELAY_2MS);
	  }
	  
	  vfnLCD_SendLine(4, u8MLCD_INIT4);

	  u16tempo = 500;

	  while(--u16tempo)
	  {
	 	vfnLCD_Delay(DELAY_2MS);
	  }

	  
}


void vfnLCD_Init (uint8 u8lcd)
{
    vfnLCD_GPIO_Init ();

    vfnLCD_Delay(DELAY_2MS);
    vfnLCD_Delay(DELAY_2MS);
    vfnLCD_Delay(DELAY_2MS);
    vfnLCD_Delay(DELAY_2MS);
    vfnLCD_Delay(DELAY_2MS);
    
  
    LCD_MODE = LCD_INSTRUCTION;

    LCD_DATA_7 = 0;
    LCD_DATA_6 = 0;
    LCD_DATA_5 = 1;
    LCD_DATA_4 = 1;
    
    LCD_SEND_CLOCK();
    
    vfnLCD_Delay(DELAY_2MS);
    vfnLCD_Delay(DELAY_2MS);
    
    LCD_DATA_7 = 0;
    LCD_DATA_6 = 0;
    LCD_DATA_5 = 1;
    LCD_DATA_4 = 1;
    
    LCD_SEND_CLOCK()
    
    vfnLCD_Delay(DELAY_100US);
    
    LCD_DATA_7 = 0;
    LCD_DATA_6 = 0;
    LCD_DATA_5 = 1;
    LCD_DATA_4 = 1;
    
    LCD_SEND_CLOCK()
    
    vfnLCD_Delay(DELAY_100US);
    
    LCD_DATA_7 = 0;
    LCD_DATA_6 = 0;
    LCD_DATA_5 = 1;
    LCD_DATA_4 = 0;
    
    LCD_SEND_CLOCK()
    
    vfnLCD_Delay(DELAY_40US);
    
    vfnLCD_SendData (u8lcd, 0x28);  //4 bit interface, 2 lines
    
    
    vfnLCD_SendData (u8lcd, 0x01);  //Erase all DRAM
    
    vfnLCD_Delay(DELAY_2MS);
    
    vfnLCD_SendData (u8lcd, 0x02);  //Returns LCD window to its default pos
    
    vfnLCD_Delay(DELAY_2MS);
        
    vfnLCD_SendData (u8lcd, LCD_INIT_CURSOR_BLINKING);  //LCD ON, CURSOR, BLINKING
    
    //Symbols init
    vfnLCD_SendData (u8lcd, 0x40);   //User CGRAM first position
    
    LCD_MODE = LCD_DATA_MODE;
    vfnLCD_SendData (u8lcd, 0b00011111);  // Signal Strength symbol @ 0x00
    vfnLCD_SendData (u8lcd, 0b00010001);
    vfnLCD_SendData (u8lcd, 0b00001010);
    vfnLCD_SendData (u8lcd, 0b00001010);
    vfnLCD_SendData (u8lcd, 0b00000100);
    vfnLCD_SendData (u8lcd, 0b00000100);
    vfnLCD_SendData (u8lcd, 0b00000100);
    vfnLCD_SendData (u8lcd, 0b00000100);

    vfnLCD_SendData (u8lcd, 0b00001110);  // Battery level symbol @ 0x01
    vfnLCD_SendData (u8lcd, 0b00011111);
    vfnLCD_SendData (u8lcd, 0b00010001);
    vfnLCD_SendData (u8lcd, 0b00010011);
    vfnLCD_SendData (u8lcd, 0b00010111);
    vfnLCD_SendData (u8lcd, 0b00011111);
    vfnLCD_SendData (u8lcd, 0b00011111);
    vfnLCD_SendData (u8lcd, 0b00011111);
   
    vfnLCD_SendData (u8lcd, 0b00000000);  // Menu select symbol @ 0x02
    vfnLCD_SendData (u8lcd, 0b00011000);
    vfnLCD_SendData (u8lcd, 0b00011100);
    vfnLCD_SendData (u8lcd, 0b00001110);
    vfnLCD_SendData (u8lcd, 0b00000111);
    vfnLCD_SendData (u8lcd, 0b00001110);
    vfnLCD_SendData (u8lcd, 0b00011100);
    vfnLCD_SendData (u8lcd, 0b00011000);
   
    vfnLCD_SendData (u8lcd, 0b00000111);  // Motor symbol @ 0x03
    vfnLCD_SendData (u8lcd, 0b00000101);
    vfnLCD_SendData (u8lcd, 0b00000111);
    vfnLCD_SendData (u8lcd, 0b00000000);
    vfnLCD_SendData (u8lcd, 0b00011011);
    vfnLCD_SendData (u8lcd, 0b00010101);
    vfnLCD_SendData (u8lcd, 0b00010101);
    vfnLCD_SendData (u8lcd, 0b00010001);
   
   	vfnLCD_SendData (u8lcd, 0b00000111);  // Motor driver symbol @ 0x04
    vfnLCD_SendData (u8lcd, 0b00000101);
    vfnLCD_SendData (u8lcd, 0b00000111);
    vfnLCD_SendData (u8lcd, 0b00000000);
    vfnLCD_SendData (u8lcd, 0b00011100);
    vfnLCD_SendData (u8lcd, 0b00010010);
    vfnLCD_SendData (u8lcd, 0b00010010);
    vfnLCD_SendData (u8lcd, 0b00011100);
    
    vfnLCD_SendData (u8lcd, 0b00001000);  //GPS symbol @ 0x05
	vfnLCD_SendData (u8lcd, 0b00010011);    
    vfnLCD_SendData (u8lcd, 0b00010100);    
    vfnLCD_SendData (u8lcd, 0b00010101);    
    vfnLCD_SendData (u8lcd, 0b00010101);    
    vfnLCD_SendData (u8lcd, 0b00010100);    
    vfnLCD_SendData (u8lcd, 0b00010011);    
    vfnLCD_SendData (u8lcd, 0b00001000);    
    
	vfnLCD_SendData (u8lcd, 0b00000100);    // Ultrasonic sensor symbol @ 0x06
    vfnLCD_SendData (u8lcd, 0b00000000);    
    vfnLCD_SendData (u8lcd, 0b00001110);    
    vfnLCD_SendData (u8lcd, 0b00000000);    
    vfnLCD_SendData (u8lcd, 0b00011111);    
    vfnLCD_SendData (u8lcd, 0b00000000);    
    vfnLCD_SendData (u8lcd, 0b00011111);    
    vfnLCD_SendData (u8lcd, 0b00000000);    
    
    vfnLCD_SendData (u8lcd, 0b00000000);    //HBLED symbol @0x07
    vfnLCD_SendData (u8lcd, 0b00000000);    
    vfnLCD_SendData (u8lcd, 0b00001010);    
    vfnLCD_SendData (u8lcd, 0b00010001);    
    vfnLCD_SendData (u8lcd, 0b00000100);    
    vfnLCD_SendData (u8lcd, 0b00010001);    
    vfnLCD_SendData (u8lcd, 0b00001010);    
    vfnLCD_SendData (u8lcd, 0b00000000);    
}
  /*
void vfnLCD_Delay (uint8 u8delay)
{
    uint8 u8bleh = u8delay;
    while(u8delay--);
    while(u8bleh--);
    return;														  
}   */
 
void vfnLCD_Delay(uint8 u8cycles)
{
    uint8 u8current_cnt;
    uint8 u8target;
    
    u8current_cnt = u8TPM_GetTimerCounter(GENERAL_TIME_BASE_TIMER);
    
    u8target = u8current_cnt + u8cycles;
    
    while(u8current_cnt != u8target)
    {
        u8current_cnt = u8TPM_GetTimerCounter(GENERAL_TIME_BASE_TIMER);    
    }
}

void vfnLCD_setBlinking(uint8 u8line, uint8 u8mode)
{
    LCD_MODE = LCD_INSTRUCTION;
    vfnLCD_SendData(u8line,u8mode);
}

void vfnLCD_putBuffer1(uint8 *u8string)
{
    uint8 u8c=15;
    do{
        u8LCD_Buffer1[u8c]=u8string[u8c];    
    }while(u8c--);
}

void vfnLCD_putBuffer2(uint8 *u8string)
{
    uint8 u8c=15;
    do{
        u8LCD_Buffer2[u8c]=u8string[u8c];    
    }while(u8c--);
}

void vfnLCD_putBuffer3(uint8 *u8string)
{
    uint8 u8c=15;
    do{
        u8LCD_Buffer3[u8c]=u8string[u8c];    
    }while(u8c--);
}

void vfnLCD_putBuffer4(uint8 *u8string)
{
    uint8 u8c=15;
    do{
        u8LCD_Buffer4[u8c]=u8string[u8c];    
    }while(u8c--);
}

void vfnLCD_SendLine (uint8 u8line, uint8 *u8string)
{
    uint8 u8counter;
    if (u8line == 1)
    {
        // First choose the correct LCD line
        LCD_MODE = LCD_INSTRUCTION;
        vfnLCD_SendData (LCD_DISPLAY_ONLY_1, 0x80);
        
        // Send the data string
        LCD_MODE = LCD_DATA_MODE; 
        for (u8counter = 0; u8counter < 16; u8counter++)
        {
            vfnLCD_SendData (LCD_DISPLAY_ONLY_1, u8string[u8counter]);
        }
        
        //LCD_MODE = LCD_INSTRUCTION;
        //vfnLCD_SendData(LCD_DISPLAY_ONLY_1,u8LCD_cursor1);
        //These two lines are eliminated because line 2 is always sent after line 1
           
    }
    else if (u8line == 2)
    {
        // First choose the correct LCD line
        LCD_MODE = LCD_INSTRUCTION;
        vfnLCD_SendData (LCD_DISPLAY_ONLY_1, 0xC0);
        
        // Send the data string
        LCD_MODE = LCD_DATA_MODE; 
        for (u8counter = 0; u8counter < 16; u8counter++)
        {
            vfnLCD_SendData (LCD_DISPLAY_ONLY_1, u8string[u8counter]);
        }
        
        LCD_MODE = LCD_INSTRUCTION;
        vfnLCD_SendData(LCD_DISPLAY_ONLY_1,u8LCD_cursor1);
        
            
    }
    else if (u8line == 3)
    {
        // First choose the correct LCD line
        LCD_MODE = LCD_INSTRUCTION;
        vfnLCD_SendData (LCD_DISPLAY_ONLY_2, 0x80);
        
        // Send the data string
        LCD_MODE = LCD_DATA_MODE;
        for (u8counter = 0; u8counter < 16; u8counter++)
        {
            vfnLCD_SendData (LCD_DISPLAY_ONLY_2, u8string[u8counter]);
        }
        
        //LCD_MODE = LCD_INSTRUCTION;
        //vfnLCD_SendData(LCD_DISPLAY_ONLY_2,u8LCD_cursor2);
        //These two lines are eliminated because line 4 is always sent after line 3
             
    }
    else
    {
        // First choose the correct LCD line
        LCD_MODE = LCD_INSTRUCTION;
        vfnLCD_SendData (LCD_DISPLAY_ONLY_2, 0xC0);
        
        // Send the data string
        LCD_MODE = LCD_DATA_MODE; 
        for (u8counter = 0; u8counter < 16; u8counter++)
        {
            vfnLCD_SendData (LCD_DISPLAY_ONLY_2, u8string[u8counter]);
        }
        
        LCD_MODE = LCD_INSTRUCTION;
        vfnLCD_SendData(LCD_DISPLAY_ONLY_2,u8LCD_cursor2);
        
    }
}


